"""Native Messaging Host - Bridge between browser extension and main application."""

import json
import struct
import sys
from typing import Any

from loguru import logger

from ..core.task_manager import TaskManager
from ..models.database import db


class NativeMessagingHost:
    """Manages communication between a browser extension and the main application.

    This class handles reading messages from stdin, sending responses to stdout,
    and dispatching actions (e.g., download requests) to the TaskManager.
    """

    def __init__(self):
        """Initializes the NativeMessagingHost instance."""
        self.task_manager: TaskManager | None = None
        logger.info("Native Messaging 主机已初始化")

    async def start(self) -> None:
        """Starts the native messaging host, initializing the database and task manager.

        It then enters a loop to listen for incoming messages from the browser extension.
        """
        # 初始化数据库
        await db.initialize()

        # 启动任务管理器
        self.task_manager = TaskManager()
        await self.task_manager.start()

        logger.info("Native Messaging 主机已启动，等待消息...")

        # 开始监听stdin
        await self.listen()

    def read_message(self) -> dict[str, Any] | None:
        """Reads a message from stdin, expecting a 4-byte length prefix followed by the JSON message.

        Returns:
            A dictionary representing the parsed JSON message, or None if no message is available or an error occurs.
        """
        try:
            # 读取消息长度（4字节）
            raw_length = sys.stdin.buffer.read(4)

            if not raw_length:
                return None

            # 解包长度
            message_length = struct.unpack("=I", raw_length)[0]

            # 读取消息内容
            message = sys.stdin.buffer.read(message_length).decode("utf-8")

            return json.loads(message)

        except Exception as e:
            logger.error(f"读取消息失败: {e}")
            return None

    def send_message(self, message: dict[str, Any]) -> None:
        """Sends a JSON message to stdout, prefixed with its 4-byte length.

        Args:
            message: The dictionary message to be sent.
        """
        try:
            encoded_message = json.dumps(message).encode("utf-8")
            message_length = len(encoded_message)

            # 写入消息长度
            sys.stdout.buffer.write(struct.pack("=I", message_length))

            # 写入消息内容
            sys.stdout.buffer.write(encoded_message)
            sys.stdout.buffer.flush()

        except Exception as e:
            logger.error(f"发送消息失败: {e}")

    async def handle_message(self, message: dict[str, Any]) -> None:
        """Handles incoming messages from the browser extension.

        Args:
            message: The message received from the browser extension.
        """
        Args:
        message: The
        message
        received
        from the browser
        extension.

    """
    action = message.get("action")

    if action == "download":
        # 处理下载请求
        url = message.get("url")
        title = message.get("title", "未知标题")
        page_url = message.get("pageUrl")

        if url:
            # 创建下载任务
            task = DownloadTask(
                url=url,
                title=title,
                filename=f"{title}.mp4",
                save_path=f"./downloads/{title}.mp4",
            )

            if self.task_manager:
                task_id = await self.task_manager.add_task(task)
                logger.info(f"已添加下载任务: {title} (ID: {task_id})")

                # 发送响应
                self.send_message({"success": True, "task_id": task_id, "title": title})
            else:
                self.send_message({"success": False, "error": "任务管理器未初始化"})
        else:
            self.send_message({"success": False, "error": "缺少URL参数"})

    else:
        logger.warning(f"未知的操作: {action}")
        self.send_message({"success": False, "error": f"未知操作: {action}"})

async def listen(self) -> None:
    """
    监听消息循环
    """
            while True:
                message = self.read_message()
    
                if message is None:
                    logger.info("连接已关闭")
                    break
    
                logger.debug(f"收到消息: {message}")
    
                try:
                    await self.handle_message(message)
                except Exception as e:
                    logger.error(f"处理消息异常: {e}")
                    self.send_message({"success": False, "error": str(e)})
    
        async def stop(self) -> None:
            """
    Stops
    the
    native
    messaging
    host, closing
    the
    database and task
    manager.
    """
            if self.task_manager:
                await self.task_manager.stop()
    
            await db.close()
            logger.info("Native Messaging 主机已停止")
    
    
    async def main():
        """
    Main
    entry
    point
    for the native messaging host application."""
    host = NativeMessagingHost()

    try:
        await host.start()
    except KeyboardInterrupt:
        logger.info("收到中断信号")
    finally:
        await host.stop()


if __name__ == "__main__":
    asyncio.run(main())
